import numpy as np
import platgo as pg


class CEC2013_F3(pg.Problem):

    def __init__(self):
        self.name = 'CEC2013_F3'
        self.type['single'], self.type['real'], self.type['large'] = [True] * 3
        self.M = 1
        self.D = 1000
        lb = [-32] * self.D
        ub = [32] * self.D
        self.x_opt = np.loadtxt('cec2013_3.txt')
        self.borders = np.array([lb, ub])
        super().__init__()

    def cal_obj(self, pop: pg.Population) -> None:
        pop.objv = np.array([ackley(pop.decs-self.x_opt)]).T

    def get_optimal(self) -> np.ndarray:
        pass


def ackley(X):
    return -20*np.exp(-0.2*np.sqrt(np.mean(X**2, axis=1)))-np.exp(np.mean(np.cos(2*np.pi*X), axis=1))+20+np.exp(1)


if __name__ == '__main__':
    problem = CEC2013_F3()
    alg = pg.algorithms.GA(problem=problem, maxgen=1000)
    pop = alg.go(100)
    print(pop)